use crate::conf::config::{Config, DataBase, Server};
use serde::Serialize;
use serde::de::DeserializeOwned;
use std::collections::HashMap;
use std::fs;

fn parse() {
    let mut _ads: HashMap<String, DataBase> = HashMap::new();
    _ads.insert(
        "mysql".to_string(),
        DataBase {
            host: "192.168.8.20:3307".to_string(),
            username: "root".to_string(),
            password: "root".to_string(),
            database: "1Panel".to_string(),
        },
    );
    let mut config = Config {
        server: Server {
            id: 1,
            name: "asd".to_string(),
        },
        database: _ads,
        visible: Some(true),
    };
    let test = ParseTest {};
    let toml_path = "/home/debi/IdeaProjects/RustLearn/Work/steam/src/conf/toml.toml";
    test.write_toml(config, toml_path);
    test.read_toml(toml_path);

    config = Config {
        server: Server {
            id: 1,
            name: "asd".to_string(),
        },
        database: HashMap::new(),
        visible: Some(false),
    };

    let json_path = "/home/debi/IdeaProjects/RustLearn/Work/steam/src/conf/json.json";
    test.write_json(config, json_path);
    test.read_json(json_path);
}

trait ParseFor {
    fn to_file<T>(t: T, path: &str)
    where
        T: Serialize;
    fn file_to<'a, T>(path: &str) -> T
    where
        T: DeserializeOwned;
}

struct TomlParse;

struct JsonParse;

struct ParseTest {}

impl ParseTest {
    pub fn read_toml(&self, path: &str) {
        let from1 = TomlParse::file_to::<Config>(path);
        println!("{:?}", from1)
    }
    pub fn write_toml(&self, config: Config, path: &str) {
        TomlParse::to_file::<Config>(config, path)
    }
    pub fn write_json(&self, config: Config, path: &str) {
        JsonParse::to_file::<Config>(config, path)
    }
    pub fn read_json(&self, path: &str) {
        let from1 = JsonParse::file_to::<Config>(path);
        println!("{:?}", from1)
    }
}

impl ParseFor for TomlParse {
    fn to_file<T>(t: T, path: &str)
    where
        T: Serialize,
    {
        let toml = toml::to_string_pretty(&t).unwrap();
        fs::write(path, toml.as_bytes()).unwrap();
    }
    fn file_to<'a, T>(path: &str) -> T
    where
        T: DeserializeOwned,
    {
        let contents = fs::read_to_string(path).expect("Read file error!");
        toml::from_str(contents.as_str()).unwrap()
    }
}

impl ParseFor for JsonParse {
    fn to_file<T>(t: T, path: &str)
    where
        T: Serialize,
    {
        let j = serde_json::to_string(&t).unwrap();
        fs::write(path, j.as_bytes()).unwrap();
    }
    fn file_to<'a, T>(path: &str) -> T
    where
        T: DeserializeOwned,
    {
        let contents = fs::read_to_string(path).expect("Read file error!");
        serde_json::from_str(contents.as_str()).unwrap()
    }
}
